home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990, 1991 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/collab/TimeLine/RCS/moveCanvas.c,v 1.0 91/09/30 16:58:54 chua Exp Locker: drapeau $ */
- /* $Log: moveCanvas.c,v $
- * Revision 1.0 91/09/30 16:58:54 chua
- * Update to version 1.0
- *
- * Revision 0.47 91/09/23 17:11:48 chua
- * In ResetCanvas, clear any selected region.
- *
- * Revision 0.46 91/09/20 13:05:30 chua
- * In ResetCanvas, also move the playback head back to zero.
- *
- * Revision 0.45 91/09/19 17:28:54 chua
- * Make sure that variables are initialized properly. Change formatting slightly,
- * so that (if, for, while) statements with only one statement in them will not have
- * braces.
- *
- * Revision 0.44 91/08/05 16:53:14 chua
- * Deleted the RepaintCanvas routine, as it is no longer necessary. In places where it
- * is called, just call the ScrollToFirstQuarter routine, which will do the necessary
- * repaint as well.
- *
- * Revision 0.43 91/08/05 13:03:03 chua
- * Added the routines to scroll fast the canvas both left and right, and also to reset the canvas
- * back to the starting position.
- *
- * In the ScrollToMiddle function, change the name to ScrollToFirstQuarter. Now, we position
- * the parameter, quarter, to the first quarter of the canvas, instead of in the middle, as
- * previously.
- *
- * Revision 0.42 91/07/22 15:18:38 chua
- * Added a new procedure, ScrollToMiddle, which will scroll or remap the canvas, such that the
- * position given by the parameter, middle, will be in the center of the canvas.
- *
- * Revision 0.41 91/07/17 10:27:12 chua
- * *** empty log message ***
- *
- * Revision 0.40 91/07/17 10:24:44 chua
- * This file contains the functions dealing with the scrolling of the canvas, or
- * remapping the canvas to another part of the TimeLine.
- * It also contains the notify procedures for the move canvas left and move canvas
- * right buttons.
- *
- * The functions dealing with the scrolling/remapping of the draw canvas are:
- *
- * ShowNewCanvas
- * VerticalScrollHandler
- * HorizontalScrollHandler
- * CheckHorizontalScrolling
- * CheckVerticalScrolling
- * */
-
- static char moveCanvasrcsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/moveCanvas.c,v 1.0 91/09/30 16:58:54 chua Exp Locker: drapeau $";
- #include "main.h"
-
- /*
- * Notify callback function for `MoveCanvasLeftButton'.
- * Move the canvas left by one screen.
- */
- void MoveCanvasLeft(item, event)
- Panel_item item;
- Event *event;
- {
- int viewLength;
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
-
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- if (tlFrame->canvasStart != 0)
- {
- tlFrame->canvasStart -= viewLength;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond)
- + (TimeLineInterval * PixelsPerSecond);
- if (tlFrame->canvasStart < 0)
- tlFrame->canvasStart = 0;
- ShowNewCanvas(tlFrame, 1);
- }
- }
-
- /*
- * Notify callback function for `MoveCanvasRightButton'.
- * Move the canvas right by one screen.
- */
- void MoveCanvasRight(item, event)
- Panel_item item;
- Event *event;
- {
- int viewLength;
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
-
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- tlFrame->canvasStart += viewLength;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
- ShowNewCanvas(tlFrame, 1);
- }
-
- /*
- * Notify callback function for `MoveCanvasFastLeftButton'.
- * Move the canvas left by three screen.
- */
- void MoveCanvasFastLeft(item, event)
- Panel_item item;
- Event *event;
- {
- int viewLength;
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
-
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- if (tlFrame->canvasStart != 0)
- {
- tlFrame->canvasStart -= viewLength * 3;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond)
- + (TimeLineInterval * PixelsPerSecond);
- if (tlFrame->canvasStart < 0)
- tlFrame->canvasStart = 0;
- ShowNewCanvas(tlFrame, 1);
- }
- }
-
- /*
- * Notify callback function for `MoveCanvasFastRightButton'.
- * Move the canvas right by three screen.
- */
- void MoveCanvasFastRight(item, event)
- Panel_item item;
- Event *event;
- {
- int viewLength;
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
-
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- tlFrame->canvasStart += viewLength * 3;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
- ShowNewCanvas(tlFrame, 1);
- }
-
- /*
- * Notify callback function for `ResetCanvasButton'.
- * Reset the canvas to start at time 0. Also reset the playback head position.
- */
- void ResetCanvas(item, event)
- Panel_item item;
- Event *event;
- {
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
-
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- if (tlFrame->areaSelected == 1) /* Deselect any selected region */
- {
- XDrawRectangle(tlFrame->dpyDraw, tlFrame->xidDraw, tlFrame->gcLine, (tlFrame->startX / tlFrame->zoomLevel) - tlFrame->canvasStart,
- tlFrame->startY, (tlFrame->endX - tlFrame->startX) / tlFrame->zoomLevel,
- tlFrame->endY - tlFrame->startY);
- tlFrame->startX = tlFrame->endX = tlFrame->startY = tlFrame->endY = 0;
- DrawSelectArea(tlFrame);
- }
- DeselectNote(tlFrame); /* Deselect any selected note */
- DrawPlaybackHead(-1, tlFrame);
- tlFrame->canvasStart = 0;
- ShowNewCanvas(tlFrame, 1);
- }
-
- /*
- * This function is called when we are changing the segment of timeline that is being displayed on the current canvas (moving canvas right or left, or
- * during playback scrolling).
- * It will check if any area has been selected and if it should be drawn on the new display. It will then refresh both the draw and time canvases to
- * show the new segment of the timeline.
- */
- void ShowNewCanvas(tlFrame, canvasStart)
- TimeLineFramePtr tlFrame;
- int canvasStart;
- {
- int viewLength;
-
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- if (canvasStart > tlFrame->TimeLineLength - viewLength)
- canvasStart = tlFrame->TimeLineLength - viewLength - 1;
- xv_set(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START,
- canvasStart, NULL);
- DrawCanvasRepaintHandler(tlFrame->TimeLine_window->DrawCanvas, tlFrame->paintWinDraw,
- tlFrame->dpyDraw, tlFrame->xidDraw, NULL);
- TimeCanvasRepaintHandler(tlFrame->TimeLine_window->AppCanvas, tlFrame->paintWinApp,
- tlFrame->dpyApp, tlFrame->xidApp, NULL);
- }
-
- /*
- * Notify interpose function to vertically scroll both the App canvas and Draw canvas simultaneously.
- * This is required so as to accomodate more open applications than can be displayed on the screen at the same time.
- * This function is called when the vertical scrollbar of the App canvas is pressed/moved.
- */
- Notify_value VerticalScrollHandler (win, event, arg, type)
- Xv_window win;
- Event *event;
- Notify_arg arg;
- Notify_event_type type;
- {
- int viewStart; /* The current canvas position at the left edge of the viewing window */
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects *ip;
- Canvas canvas = xv_get(win, XV_OWNER);
-
- ip = (TimeLine_window_objects *) xv_get(canvas, XV_KEY_DATA, INSTANCE);
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- switch (event_action(event))
- {
- case SCROLLBAR_REQUEST:
- viewStart = (int) xv_get (arg, SCROLLBAR_VIEW_START);
- xv_set (tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_START,
- viewStart, NULL); /* Set the canvas position of the Draw canvas to the same as for the App canvas */
- break;
- default:
- break;
- }
- return notify_next_event_func(win, (Notify_event)event, arg, type);
- }
-
- /*
- * Notify interpose function to horizontally scroll both the Draw canvas and Time canvas simultaneously.
- * This is required so that the timeline will move along with the notes during playback or scrolling done by the user.
- * This function is called when the horizontal scrollbar of the Draw canvas is pressed/moved.
- */
- Notify_value HorizontalScrollHandler (win, event, arg, type)
- Xv_window win;
- Event *event;
- Notify_arg arg;
- Notify_event_type type;
- {
- int viewStart; /* The current canvas position at the top edge of the viewing window */
- int viewLength;
- int previousStart;
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects *ip;
- Canvas canvas = xv_get(win, XV_OWNER);
-
- ip = (TimeLine_window_objects *) xv_get(canvas, XV_KEY_DATA, INSTANCE);
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- switch (event_action(event))
- {
- case SCROLLBAR_REQUEST:
- if (arg == tlFrame->DrawScrollbarHor) /* For some reason, this function gets called when the App canvas vertical scrollbar */
- { /* is pressed as well. Thus the need for the if statement so that the scrolling */
- /* is executed only if this function is called by the Draw canvas horizontal */
- /* scrollbar */
-
- viewStart = (int) xv_get (arg, SCROLLBAR_VIEW_START);
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- if (viewStart >= tlFrame->TimeLineLength - viewLength) /* Check if switching to a new canvas view is necessary */
- {
- tlFrame->canvasStart = tlFrame->canvasStart + tlFrame->TimeLineLength - viewLength;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
- ShowNewCanvas(tlFrame, 1);
- }
- else if (viewStart <= 0 && tlFrame->canvasStart != 0)
- {
- previousStart = tlFrame->canvasStart;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->TimeLineLength + viewLength;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond)
- + (TimeLineInterval * PixelsPerSecond);
- if (tlFrame->canvasStart < 0)
- tlFrame->canvasStart = 0;
- viewStart = previousStart - tlFrame->canvasStart - 1;
- ShowNewCanvas (tlFrame, viewStart);
- }
- else
- xv_set (tlFrame->TimeScrollbar, SCROLLBAR_VIEW_START, viewStart, NULL);
- scrollHorStart = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START); /* Get the canvas window horizontal and vertical start and end points */
- scrollHorEnd = scrollHorStart + xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- }
- break;
- default:
- break;
- }
- return notify_next_event_func(win, (Notify_event)event, arg, type);
- }
-
- /*
- * Function to check if horizontal scrolling is required. Scrolling is required when the user drags the mouse off the canvas window and it is not
- * at the end of the canvas. The canvas scrolls by 10 pixels each time.
- * Called by DrawCanvasRepaintHandler (canvas.c)
- */
- void CheckHorizontalScrolling (xPos, tlFrame)
- int xPos;
- TimeLineFramePtr tlFrame;
- {
- if (xPos <= scrollHorStart) /* Check if scrolling left is required */
- {
- if ((scrollHorStart = scrollHorStart - 10) < 0)
- scrollHorStart = 0;
- xv_set(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START, scrollHorStart, NULL);
- scrollHorEnd = scrollHorStart + xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- }
- else if (xPos >= scrollHorEnd) /* Check if scrolling right is required */
- {
- if ((scrollHorStart = scrollHorStart + 10) >
- tlFrame->TimeLineLength - xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH))
- scrollHorStart = tlFrame->TimeLineLength - xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- xv_set(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START, scrollHorStart, NULL);
- scrollHorEnd = scrollHorStart + xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- }
- }
-
- /*
- * Function to check if vertical scrolling is required. Scrolling is required when the user drags the mouse off the canvas window and it is not
- * at the end of the canvas. The canvas scrolls by the height of one track each time.
- * Called by DrawCanvasRepaintHandler (canvas.c)
- */
- void CheckVerticalScrolling (yPos, tlFrame)
- int yPos;
- TimeLineFramePtr tlFrame;
- {
- if (yPos <= scrollVerStart) /* Check if scrolling left is required */
- {
- if ((scrollVerStart = scrollVerStart - (IconHeight + IconGap)) < 0)
- scrollVerStart = 0;
- xv_set(tlFrame->AppScrollbar, SCROLLBAR_VIEW_START, scrollVerStart, NULL);
- scrollVerEnd = scrollVerStart + xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH);
- }
- else if (yPos >= scrollVerEnd) /* Check if scrolling right is required */
- {
- if ((scrollVerStart = scrollVerStart + (IconHeight + IconGap)) > ((tlFrame->numberOfApps + 1) * (IconHeight + IconGap)
- - xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH)))
- scrollVerStart = (tlFrame->numberOfApps+1) * (IconHeight + IconGap)
- - xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH);
- xv_set(tlFrame->AppScrollbar, SCROLLBAR_VIEW_START, scrollVerStart, NULL);
- scrollVerEnd = scrollVerStart + xv_get(tlFrame->DrawScrollbarVer, SCROLLBAR_VIEW_LENGTH);
- }
- }
-
- /*
- * This function will scroll or remap the canvas such that the value passed in by the parameter quarter, is in the first quarter of the canvas.
- * The parameter refresh indicates if we definitely want to redraw the canvas, regardless of where the quarter is already in the window.
- */
- void ScrollToFirstQuarter(tlFrame, quarter, refresh)
- TimeLineFramePtr tlFrame;
- int quarter;
- int refresh;
- {
- int scrollStart, scrollEnd;
- int viewLength;
-
- viewLength = xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_LENGTH);
- scrollStart = (xv_get(tlFrame->DrawScrollbarHor, SCROLLBAR_VIEW_START) + tlFrame->canvasStart) *
- tlFrame->zoomLevel; /* Check if it is necessary to scroll the canvas. Scrolling is done only */
- scrollEnd = scrollStart + (viewLength * tlFrame->zoomLevel); /* if the start of the note is not visible */
- if (quarter < scrollStart || quarter > scrollEnd)
- {
- tlFrame->canvasStart = (quarter / tlFrame->zoomLevel) - (viewLength / 4);
- if (tlFrame->canvasStart < 0)
- tlFrame->canvasStart = 0;
- tlFrame->canvasStart = tlFrame->canvasStart - tlFrame->canvasStart % (TimeLineInterval * PixelsPerSecond);
- ShowNewCanvas(tlFrame, 1);
- }
- else if (refresh == 1)
- ShowNewCanvas(tlFrame, 1);
- }
-